package it.unibo.refolding.pico.ui;

import it.unibo.refolding.common.LinearFunction;
import it.unibo.refolding.pico.PicoShapes;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JPanel;

public class ContactPointAndSlopeZDefPanel extends JPanel {

	private static final long serialVersionUID = 7795352732341921448L;

	private final ZDefDrawer drawer;
	final ContactPointAndSlopeHolder h;

	// TODO: Make another drawer.
	int dragFrom, dragTo;

  final double defScale;
	
	public static final int halfSquareSide = 10;

	public ContactPointAndSlopeZDefPanel(ZDefDrawer drawer, double defScale, ContactPointAndSlopeHolder h) {
		this.h = h;
		this.drawer = drawer;
		this.defScale = defScale;
		setPreferredSize(new Dimension(h.maxZ() - h.minZ(), (int) Math.ceil((h.maxDef() - h.minDef()) * defScale)));
		dragFrom = dragTo = h.size();
	}

	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		super.paintComponent(g2);
		drawer.paintComponent(g2);
		Color savedColor = g2.getColor();
		g2.setColor(Color.BLACK);
		if (h.getContactPoint() != null) {
			double x = h.getContactPoint().zLsb - halfSquareSide;
			int side = 2 * halfSquareSide + 1;
      g2.draw(new Rectangle2D.Double(x - h.minZ(), defScale
        * (h.getContactPoint().deflectionLsb - h.minDef()) - halfSquareSide, side, side));
			if (!Double.isNaN(h.slope)) {
				LinearFunction f = h.linearFunction();
				GeneralPath line = new GeneralPath();
				line.moveTo(0, defScale * (f.evaluate(h.minZ()) - h.minDef()));
				line.lineTo(h.maxZ() - h.minZ(), defScale * (f.evaluate(h.maxZ()) - h.minDef()));
				g2.draw(line);
			}
		}

		if (dragFrom != dragTo) {
			assert dragFrom != h.size();
			Path2D.Float path = PicoShapes.createPath(
				h.sharedZ(), h.sharedDef(), defScale, dragFrom, dragTo, h.minZ(), h.minDef());
			g2.setColor(Color.GRAY);
			g2.draw(path);
		}
		
		g.setColor(savedColor);
	}

	public int minZ() {
		return h.minZ();
	}

	public int minDef() {
		return h.minDef();
	}
}
